<template>
  <view class="order-template-1">
    <view class="order-num">工单明细数量：{{ orderListDTO.length }}</view>
    <view class="order-list">
      <view
        v-for="(item, index) in orderListVO"
        :key="index"
        :class="
          globalStore.connDeviceList.length && item.every((v) => v.withIn === true) ? '' : 'within'
        "
      >
        <view class="order-list-item" v-for="(order, index) in item" :key="order.id">
          <view v-if="index == 0" class="send-btn">
            <button type="primary" data-type="mainSend" @click="setData(item)">
              {{ order.main_id[1] }}:下发
            </button>
          </view>
          <view class="top">
            <text>工艺号： {{ order.name }}</text>
            <view class="work-type"> {{ order.worktype }} </view>
          </view>
          <view class="middle">
            <view class="tork">
              <view class="text">扭矩参考值</view>
              <view class="value">最小: {{ order.min_tork }} ｜ 最大: {{ order.max_tork }} </view>
            </view>
            <view class="angle">
              <view class="text">角度参考值</view>
              <view class="value">最小: {{ order.min_angle }} ｜ 最大: {{ order.max_angle }} </view>
            </view>
          </view>
          <view class="line-circle"></view>
          <view class="bottom">
            <view>
              <view class="target-tork text">目标扭力值</view>
              <view class="target-tork value"> {{ order?.target_tork || 0 }} </view>
            </view>
            <view>
              <view class="tork-unit text">扭力单位</view>
              <view class="tork-unit value"> {{ order?.tork_unit || 0 }} </view>
            </view>
            <view>
              <view class="angle text">目标角度</view>
              <view class="angle value"> {{ order?.angle || 0 }} </view>
            </view>
          </view>
          <view v-if="order.worktype.slice(-1) == 0" class="ft">
            <view class="item" data-type="result" @click="onClickResult">获取结果</view>
            <view>|</view>
            <view class="item" data-type="send" @click="setData([order])">下发数据</view>
          </view>
        </view>
      </view>
    </view>
    <view class="start-work" v-if="models && globalStore.connDeviceList.length">
      <wd-button
        size="large"
        block
        :custom-class="isWork ? 'button' : 'disable'"
        :disabled="!isWork"
        @click="onStartWork"
      >
        {{ models || '开始操作' }}
      </wd-button>
    </view>
  </view>
</template>

<script setup>
import { setIntervalImmediate } from '@/utils/system'
import { computed, ref } from 'vue'
import { pause } from 'wot-design-uni/components/common/util'
import bluetoothTool from '@/utils/bluetooth'
import {
  useOrderStore,
  useDeviceStore,
  useUserStore,
  useWorkStore,
  useGlobalStore,
} from '@/stores/'
const orderStore = useOrderStore()
const deviceStore = useDeviceStore()
const userStore = useUserStore()
const workStore = useWorkStore()
const globalStore = useGlobalStore()

// 开始工作按钮文字
const models = ref('')
// 是否正在工作
const isWork = ref(false)

// 提示框标题前缀
const loadingTitlePrefix = ref('')
// 加载框标题 -单个工单完成
const finishLoadingTitle = ref('请准备')

// 获取工单列表
const orderListDTO = computed(() => {
  return userStore.actionType === 'online' ? orderStore.orderList : orderStore.offlineOrderList
})
const orderListVO = computed(() => {
  let listArr = []
  const max = deviceStore.curDevice?.criticalData?.max_tork || 0
  // const max = 30
  const min = deviceStore.curDevice?.criticalData?.min_tork || 0
  listArr = orderListDTO.value?.map((v) => {
    // 工单列表颜色区分，标识 工单的目标扭矩是否在扳手的最小和最大值中间
    v.withIn = v.target_tork >= min && v.target_tork <= max
    return v
  })
  // 分组
  const listFilter = {}
  listArr.forEach((v) => {
    if (!listFilter[v.main_id[1]]) {
      listFilter[v.main_id[1]] = [v]
    } else {
      listFilter[v.main_id[1]].push(v)
    }
  })
  // console.log(listFilter)
  return listFilter
})

// 获取结果
function onClickResult() {
  uni.navigateTo({
    url: '/pages/work/work',
  })
}

// 下发的工单
const orders = ref([])
// 下发指令
async function setData(orderArr) {
  if (!globalStore.connDeviceList.length) {
    uni.$globalMessage.alert({
      msg: '请先连接蓝牙设备',
      title: '提示',
    })
    return
  }
  // 拷贝
  const orderList = JSON.parse(JSON.stringify(orderArr))
  if (!orderList.length) {
    uni.showToast({ title: '无工单数据', icon: 'error' })
    return
  }
  orders.value = JSON.parse(JSON.stringify(orderArr))
  uni.showLoading({
    title: '执行中...',
    mask: true,
  })

  const opts = deviceStore.getOpts()
  // 下发工单
  const cmdArr = getApp().globalData.protosUtils.cmd.getSendOrderBatchCmd(orderList) // 指令数组
  for (let i = 0; i < cmdArr.length; i++) {
    await bluetoothTool.sendToDevice(opts.write, cmdArr[i])
    // 暂停0.5秒
    await pause(500)
  }
  uni.showToast({ title: '下发成功' })
  models.value = '开始操作'
  isWork.value = true
}
// 心跳定时器
let heartbeatTimer = null
let num = 0
// 开始操作
async function onStartWork() {
  if (!globalStore.connDeviceList.length) {
    uni.$globalMessage.alert({
      msg: '请先连接蓝牙设备',
      title: '提示',
    })
    return
  }
  isWork.value = false

  for (let order of orders.value) {
    // const order = orders.value[0]
    console.log('order', order)
    const opts = deviceStore.getOpts()
    // 设置模式
    uni.showLoading({
      title: finishLoadingTitle.value,
      mask: true,
    })
    const cmd = getApp().globalData.protosUtils.cmd.setModeCmd(order)
    await bluetoothTool.sendToDevice(opts.write, cmd)
    await pause(500)
    for (let j = 0; j < 1000; j++) {
      uni.showLoading({
        title: loadingTitlePrefix.value + order.name.split('@')[0] + '执行中...',
        mask: true,
      })
      //触发心跳获取数据
      const maxItem = await getData(order)
      // console.log('找到的最大tork值为:' + j, maxItem)
      if (maxItem) {
        if (maxItem.max_tork < order.min_tork || maxItem.max_tork > order.max_tork) {
          loadingTitlePrefix.value = '重做->'
          // continue
        } else {
          saveSendData(maxItem, order)
          // console.log('保存数据:' + JSON.stringify(maxItem))
          loadingTitlePrefix.value = ''
          finishLoadingTitle.value = order.name.split('@')[0] + '完成'
          break
        }
      }
    }
    uni.hideLoading()
  }
  clearInterval(heartbeatTimer)
  // wx.offBLECharacteristicValueChange() // 只有微信

  models.value = orders.value[0].name.split('@')[1] + '全部操作完成'
  uni.showToast({
    title: orders.value[0].name.split('@')[1] + '全部操作完成！',
    icon: 'none',
  })
  orders.value = []
  finishLoadingTitle.value = '请准备'
}
// 获取数据
async function getData(item) {
  if (!item) {
    throw new Error('工单内容不能为空')
    // return
  }
  const opts = deviceStore.getOpts()
  // 发送心跳，读取数据
  function sendHeartbeat() {
    clearInterval(heartbeatTimer)
    heartbeatTimer = setIntervalImmediate(async () => {
      num++
      if (num == 1000) {
        clearInterval(heartbeatTimer)
        num = 0
      } else {
        const cmd = getApp().globalData.protosUtils.cmd.getCmd('heartbeat')
        await bluetoothTool.sendToDevice(opts.write, cmd)
      }
    }, 3000)
  }
  return new Promise((resolve, reject) => {
    const logRes = []
    loadingTitlePrefix.value = item.name.split('@')[0] + '执行中...'
    //发出心跳数据
    sendHeartbeat()
    // 开始监听来自于扳手的数据
    let tork_value = Math.round(item.min_tork * 10) / 100
    let min_tork = tork_value.toFixed(2)

    uni.$on(uni.$myNotifyEventName, (data) => {
      // console.log('data:', data)
      if (data.length === 0) {
        // sendHeartbeat()
        return
      }
      let logItem = getApp().globalData.protosUtils.formatDeviceData(data) //这里的cmdVal是readType=log的心跳数据
      // console.log('logItem', JSON.stringify(logItem));
      //当瞬时扳手数据大于最小值的10%时，开始收集数据
      // if (logItem.tork >= min_tork) {
      //   logRes.push(logItem)
      //   //当瞬时扳手数据小于最小值的10%，采集停止，然后求最大值即为扳手的peek峰值
      // } else if (logItem.tork <= min_tork && logRes.length != 0) {
      //   clearInterval(heartbeatTimer)
      //   console.log('logRes:', logRes)
      //   let torks = logRes.map((v) => v.tork)
      //   let maxTork = Math.max(...torks)
      //   const res = logRes.find((v) => v.tork == maxTork) //返回获取心跳的最大值
      //   uni.$off(uni.$myNotifyEventName)
      //   resolve(res)
      //   return
      // }
      let res = { max_tork: 0 }
      if (logItem.tork >= min_tork || (logItem.tork != null && logItem.max_tork >= min_tork)) {
        logRes.push(logItem)
        //当瞬时扳手数据小于最小值的10%，采集停止，然后求最大值即为扳手的peek峰值
      } else if (logItem.tork <= min_tork && logRes.length != 0) {
        clearInterval(heartbeatTimer)
        logRes.push(logItem)
        console.log('logRes:', logRes)
        logRes.forEach((obj) => {
          if (obj.max_tork > res.max_tork) {
            res = obj
          }
        })
        console.log('res:', res)

        uni.$off(uni.$myNotifyEventName)
        resolve(res)
        return
      }
    })
  })
}

// 保存数据
function saveSendData(data, order) {
  //data: {"datetime_work": "2024-03-30 01:15:34", "datetime_work1": "2024-03-30 09:15:34", "tork": "7.13", "min_tork": "0.71", "max_tork": "7.13", "angle": "1.70", "min_angle": "1.70", "max_angle": "1.70", "wrench_identity": "", "unit": "Nm"}
  const { datetime_work, datetime_work1, max_tork, angle, unit } = data
  // console.log('order', order)
  //['工艺号 / 数据库 ID','工艺号','工单号','工位','实际值','扭力单位','扭矩允许最低值','扭矩允许最大值',
  //'实际角度值','目标角度值','角度下限','角度上限','Company','操作人员 / 数据库 ID','扳手ID','操作时间','说明']

  let workItem = {
    orderId: order.id,
    name: order.name,
    orerName: order.name.split('@')[1],
    orderPos: order.name.split('@')[0],
    real_tork: max_tork,
    unit: unit || order.unit,
    min_tork: order.min_tork,
    max_tork: order.max_tork,
    real_angle: order.worktype.toUpperCase().startsWith('A1') ? 0 : angle,
    target_angle: order.angle,
    min_angle: order.worktype.toUpperCase().startsWith('A1') ? 0 : order.min_angle,
    max_angle: order.worktype.toUpperCase().startsWith('A1') ? 0 : order.max_angle,
    company_id: '',
    operator_id: '',
    wrench_identity: deviceStore.curDevice.deviceId,
    datetime_work,
    datetime_work1,
    remark: '',
    device_name: deviceStore.curDevice.name,
    // device_proto: deviceStore.curProto,
  }

  const params = {
    workmanship_id: order.id,
    datetime_work: datetime_work,
    real_tork: max_tork,
    real_angle: order.worktype.toUpperCase().startsWith('A1') ? 0 : angle,
    wrench_identity: deviceStore.curDevice.deviceId,
    // operator_id: '',
    company_id: '',
  }
  if (userStore.actionType === 'online') {
    //当既有在线数据又有离线数据时，并且当前是在离线下，上传服务器即分享文件时，保证excel 文件中的在线及离线数据都有company_id及operator
    workItem.company_id = userStore.userInfo.company_id
    workItem.operator_id = userStore.userInfo.username
    params.company_id = userStore.userInfo.company_id
    // params.company_id =item.company_id[0];
  } else {
    workItem.company_id = order.company_code
    workItem.operator_id = order.user.split('(')[0]
    // console.log('dbh-workItem',workItem)
  }
  console.log('params', params)
  console.log('workItem', workItem)
  workStore.addWorkData({ params, workItem })
}

// onMounted(() => {
//   orderList.value =
//     userStore.actionType === 'online' ? orderStore.orderList : orderStore.offlineOrderList
// })
</script>

<style lang="scss" scoped>
.order-template-1 {
  .order-num {
    margin: 10px 0;
    color: $text-font-color-2;
  }
  .order-list {
    margin-bottom: 60px;
    .within {
      opacity: 0.6;
      pointer-events: none;
    }
    &-item {
      padding: 12px;
      // margin: 10px 0;
      margin-bottom: 14px;
      border-radius: $my-border-radius-base;
      background: $my-background-color-1;
      box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
      overflow: hidden;
      .send-btn {
        @include flex-box;
        padding-bottom: 10px;
        border-bottom: $common-border-dark;
        margin-bottom: 10px;
      }
      .top {
        @include flex-box;
        padding-bottom: 10px;
        border-bottom: $common-border-dark;
        margin-bottom: 10px;
        .work-type {
          color: $my-color-green;
        }
      }
      .middle {
        .tork {
          @include flex-box;
          font-size: $my-text-font-size-base;
          color: $text-font-color-2;
        }
        .angle {
          @extend .tork;
          margin-top: 4px;
        }
      }
      .line-circle {
        position: relative;
        height: 1px;
        margin: 14px 4px;
        border-bottom: 1px dashed $my-border-color-dark;

        &::before,
        &::after {
          content: '';
          position: absolute;
          top: -14px;
          width: 26px;
          height: 26px;
          background: $my-background-color-2;
          border-radius: 50%;
        }
        &::before {
          left: -30px;
        }
        &::after {
          right: -30px;
        }
      }
      .bottom {
        @include flex-box();
        text-align: center;
        font-size: $my-text-font-size-base;
        color: $brand-theme-color;
        .value {
          margin-top: 4px;
          font-weight: 700;
        }
      }
      .ft {
        @include flex-box-set(around, center);
        margin: 14px -12px -14px;
        text-align: center;
        background: $my-background-color-grey;
        color: $text-font-color-2;
        .item {
          padding: 10px;
          flex: 1;
        }
      }
    }
  }
  .start-work {
    width: 100%;
    position: fixed;
    // bottom: calc(var(--window-bottom) + 10px);
    bottom: var(--window-bottom);
    margin-left: -12px;
    padding: 0 12px;
    margin-bottom: 16px;
    .button {
      background: linear-gradient(136deg, #286aff, #4e6ef2, #7274f9, #9f66ff);
      box-shadow: 0 4px 14px rgba(3, 3, 3, 0.3);
    }
    .disable {
      opacity: 1;
      background: $my-background-color-disable;
      // filter: grayscale(100%);
    }
  }
}
</style>
